package com.heima.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.heima.dao.WmMaterialDao;
import com.heima.dao.WmNewsMaterialDao;
import com.heima.dto.NewsAuthDto;
import com.heima.dto.WmNewsDto;
import com.heima.dto.WmNewsPageReqDto;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.entity.KafkaMessageConstants;
import com.heima.model.wemedia.entity.WmMaterial;
import com.heima.model.wemedia.entity.WmNews;
import com.heima.dao.WmNewsDao;
import com.heima.model.wemedia.entity.WmUser;
import com.heima.service.WmNewsService;
import com.heima.service.WmUserService;
import com.heima.utils.WmThreadLocalUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;


import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 自媒体文章表(WmNews)表服务实现类
 *
 * @author makejava
 * @since 2022-04-12 15:35:31
 */
@Service("wmNewsService")
public class WmNewsServiceImpl implements WmNewsService {
    @Resource
    private WmNewsDao wmNewsDao;
    @Resource
    private WmMaterialDao wmMaterialDao;
    @Resource
    private WmNewsMaterialDao wmNewsMaterialDao;
    @Resource
    private KafkaTemplate kafkaTemplate;
    @Resource
    private WmUserService wmUserService;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public NewsAuthDto queryById(Long id) {
        WmNews wmNews = wmNewsDao.queryById(id);
        Integer userId = WmThreadLocalUtil.getUser().getId();
        WmUser wmUser = wmUserService.queryById(userId);
        NewsAuthDto newsAuthDto = new NewsAuthDto();
        BeanUtils.copyProperties(wmNews,newsAuthDto);
        newsAuthDto.setSubmitedTime(wmNews.getUpdatedTime());
        newsAuthDto.setNickname(wmUser.getNickname());
        return newsAuthDto;

    }

    /**
     * 分页查询
     *
     * @param wmNews 筛选条件
     * @param pageRequest      分页对象
     * @return 查询结果
     */
/*
    @Override
    public Page<WmNews> queryByPage(WmNews wmNews, PageRequest pageRequest) {
        long total = this.wmNewsDao.count(wmNews);
        return new PageImpl<>(this.wmNewsDao.queryAllByLimit(wmNews, pageRequest), pageRequest, total);
    }
*/

    /**
     * 新增数据
     *
     * @param wmNews 实例对象
     * @return 实例对象
     */
    @Override
    public WmNews insert(WmNews wmNews) {
        this.wmNewsDao.insert(wmNews);
        return wmNews;
    }

    @Override
    public WmNews update(WmNews wmNews) {
        return null;
    }

    /**
     * 修改数据
     *
     * @param wmNews 实例对象
     * @return 实例对象
     */
/*    @Override
    public WmNews update(WmNews wmNews) {
        this.wmNewsDao.update(wmNews);
        return this.queryById(wmNews.getId());
    }*/

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public ResponseResult deleteById(Long id) {
        WmNews wmNews = wmNewsDao.queryById(id);

        if (wmNews == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }

        if (wmNews.getStatus().equals(9)) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NO_OPERATOR_AUTH, "文章已发布, 不能删除!");
        }

        this.wmNewsDao.deleteById(id);

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 自媒体文章发布 , 修改 , 保存草稿
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult submit(WmNewsDto dto) {
        //判断参数
        if (StringUtils.isBlank(dto.getContent()) || StringUtils.isBlank(dto.getTitle())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //2. 封装数据
        WmNews wmNews = new WmNews();
        //批量复制数据到目标对象 (属性名称和类型完成一致)  type : 布局类型    images : 封面图片
        BeanUtils.copyProperties(dto, wmNews);
        //2.1 抽取内容中的图片
        List<Map> contentList = JSON.parseArray(dto.getContent(), Map.class);//转化类型
        List<String> contentImages = contentList.stream().filter(map -> "image".equals(map.get("type")))
                .map(map -> map.get("value").toString()).collect(Collectors.toList());
        //2.2 抽取封面图片
        List<String> coverImages = dto.getImages();
        //2.3 封装type数据
        if (dto.getType() == -1) {
            if (contentImages.size() >= 3) {
                coverImages = contentImages.stream().limit(3).collect(Collectors.toList());
                wmNews.setType(3);
            }
            if (contentImages.size() < 3 && contentImages.size() > 0) {
                coverImages = contentImages.stream().limit(1).collect(Collectors.toList());
                wmNews.setType(1);
            }
            if (contentImages.size() == 0) {
                coverImages = Collections.EMPTY_LIST;
                wmNews.setType(0);
            }
        }
        //2.4 封装封面图片数据
        if (CollectionUtils.isNotEmpty(coverImages)) {
            wmNews.setImages(StringUtils.join(coverImages, ","));
        }
        //3. 保存文章数据  新增  修改
        saveOrUpdate(wmNews);
        //4. 保存素材和文章的关联数据
        //4.1 保存文章和内容素材的引用关系
        saveContentImageRelation(wmNews, contentImages);
        //4.2 保存文章和封面素材的引用关系
        saveCoverImageRelation(wmNews, coverImages);
        //发送审核消息---------------------------------
        //发送消息通知审核服务进行文章审核 , 状态为 1 : 提交（待审核） 才需要审核
        if (wmNews.getStatus() == 1) {
            kafkaTemplate.send(KafkaMessageConstants.WM_NEWS_AUTO_SCAN_TOPIC, wmNews.getId().toString());
        }


        return ResponseResult.okResult("发布成功!");
    }

    /**
     * 查询文章列表
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult list(WmNewsPageReqDto dto) {
        //1. 参数校验
        if (dto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        dto.checkParam();
        //2. 封装查询条件
        Map<String, Object> queryParam = BeanUtil.beanToMap(dto);
        queryParam.put("userId",WmThreadLocalUtil.getUser().getId());
        //3. 执行查询
        PageHelper.startPage(dto.getPage(),dto.getSize());
       Page<WmNews> page= wmNewsDao.queryByMap(queryParam);
        //4. 封装数据返回
        PageResponseResult result = new PageResponseResult(dto.getPage(), dto.getSize(), (int) page.getTotal());
        result.setData(page.getResult());
        return result;
    }
    /**
     * 查询文章列表
     * @param dto
     * @return
     * admin
     */
    @Override
    public ResponseResult list1(NewsAuthDto dto) {
        //1. 参数校验
        if (dto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        dto.checkParam();
        //2. 封装查询条件
        //线程得到用户ID
        Integer userId = WmThreadLocalUtil.getUser().getId();
        dto.setUserId(userId);
        //得到作者名字
        WmUser wmUser = wmUserService.queryById(userId);

        List<NewsAuthDto> list=new ArrayList<>();
        //3. 执行查询
        PageHelper.startPage(dto.getPage(),dto.getSize());
        Page<WmNews> page= wmNewsDao.queryBylist(dto);
        for (WmNews wmNews : page) {
            NewsAuthDto newsAuthDto = new NewsAuthDto();
            BeanUtil.copyProperties(wmNews,newsAuthDto);
            newsAuthDto.setNickname(wmUser.getNickname());
            newsAuthDto.setSubmitedTime(wmNews.getUpdatedTime());
            list.add(newsAuthDto);
        }
        //4. 封装数据返回
        PageResponseResult result = new PageResponseResult(dto.getPage(), dto.getSize(), (int) page.getTotal());
        result.setData(list);
        return result;
    }
    /**
     * 审核失败or成功
     * @param
     * @return
     * admin
     */
    @Override
    public void fail(NewsAuthDto dto) {
       wmNewsDao.fail(dto);

    }
    @Override
    public void pass(NewsAuthDto dto) {
        wmNewsDao.pass(dto);

    }

    /**
     * 保存文章和封面图片的关系
     * 0: 内容引用  1 : 主图引用
     *
     * @param wmNews
     * @param
     */
    private void saveCoverImageRelation(WmNews wmNews, List<String> coverImages) {
        if (CollectionUtils.isEmpty(coverImages)) {
            return;
        }
        saveImageRelation(wmNews, coverImages, (short) 0);
    }


    private void saveContentImageRelation(WmNews wmNews, List<String> contentImages) {
        if (CollectionUtils.isEmpty(contentImages)) {
            return;
        }
        saveImageRelation(wmNews, contentImages, (short) 1);
    }

    /**
     * 保存文章和素材的关联关系
     *
     * @param wmNews
     * @param images 素材URL集合
     * @param type   引用类型 0: 内容引用  1 : 主图引用
     */

    private void saveImageRelation(WmNews wmNews, List<String> images, short type) {
        //如果是草稿不需要保存关联关系
        if (wmNews.getStatus() == 0) {
            return;
        }
        //1. 根据URL获取素材ID
        //1.1 查询素材列表
        images = images.stream().distinct().collect(Collectors.toList());//去重
        List<WmMaterial> materialList = wmMaterialDao.queryByUrls(images);
        //1.2 提取素材ID
        List<Long> ids = materialList.stream().map(wmMaterial -> wmMaterial.getId()).collect(Collectors.toList());
        //1.3 判断素材是否缺失
        if (images.size() > ids.size()) {
            throw new RuntimeException("素材数据丢失");
        }
        //2. 保存关联数据
        wmNewsMaterialDao.saveImageRelation(wmNews.getId(), ids, type);

    }

    /**
     * 保存和新增文章数据
     *
     * @param wmNews
     */
    private void saveOrUpdate(WmNews wmNews) {
        //1. id存在修改, id不存在新增
        wmNews.setUserId(Long.valueOf(WmThreadLocalUtil.getUser().getId()));
        wmNews.setCreatedTime(new Date());
        wmNews.setEnable(1);
        //新增
        if (wmNews.getId() == null) {
            wmNews.setCreatedTime(new Date());
            wmNewsDao.insert(wmNews);
            return;
        }
        //修改
        wmNewsDao.update(wmNews);
        //删除素材和文章的引用关系
        wmNewsMaterialDao.deleteById(wmNews.getId());
    }


 /*   public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        System.out.println(StringUtils.join(list, ","));
    }*/
}
